package com.hfjyz.tutor.tutor.service;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpSession;

import net.sf.jxls.reader.XLSReadStatus;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.struts2.ServletActionContext;
import org.springframework.transaction.annotation.Transactional;

import com.hfjyz.base.bean.SearchCondition;
import com.hfjyz.base.constant.BaseConstant;
import com.hfjyz.base.entity.TutorEntity;
import com.hfjyz.base.exception.BaseException;
import com.hfjyz.base.util.BaseUtil;
import com.hfjyz.base.util.ExcelUtil;
import com.hfjyz.base.util.WordUtil;
import com.hfjyz.system.user.bean.UserBean;
import com.hfjyz.tutor.tutor.bean.TutorBean;
import com.hfjyz.tutor.tutor.bean.TutorExcelBean;
import com.hfjyz.tutor.tutor.bean.TutorSearchBean;
import com.hfjyz.tutor.tutor.dao.TutorDao;

public class TutorService {
    private static final Log SYS_LOG = LogFactory.getLog(BaseConstant.SYS_LOG);
    private static final int CATEGORY_ID = 2;

    private TutorDao dao = null;

    public TutorDao getDao() {
        return dao;
    }

    public void setDao(TutorDao dao) {
        this.dao = dao;
    }

    public long getTutorCount(TutorSearchBean tutorSearch) throws BaseException {
        try {
            long count = dao.countTutor(tutorSearch);
            SYS_LOG.info("获取老师数量成功。 count=" + count);

            return count;
        } catch (Exception e) {
            SYS_LOG.error("获取老师数量失败！", e);
            throw new BaseException("获取老师数量失败！", e);
        }
    }

    public List<TutorBean> findTutor(SearchCondition cond, TutorSearchBean tutorSearch) throws BaseException {
        try {
            List<TutorEntity> entityList = dao.findTutor(cond, tutorSearch);

            List<TutorBean> beanList = new ArrayList<TutorBean>();
            for (TutorEntity entity : entityList) {
                TutorBean bean = new TutorBean(entity);
                beanList.add(bean);
            }

            SYS_LOG.info("获取老师信息成功。");
            return beanList;
        } catch (Exception e) {
            SYS_LOG.error("获取老师信息失败！", e);
            throw new BaseException("获取老师信息失败!", e);
        }
    }

    public List<TutorBean> findTutorWithoutPage(SearchCondition cond, TutorSearchBean tutorSearch) throws BaseException {
        try {
            List<TutorEntity> entityList = dao.findTutorWithoutPage(cond, tutorSearch);

            List<TutorBean> beanList = new ArrayList<TutorBean>();
            for (TutorEntity entity : entityList) {
                TutorBean bean = new TutorBean(entity);
                beanList.add(bean);
            }

            SYS_LOG.info("检索老师成功。");
            return beanList;
        } catch (Exception e) {
            SYS_LOG.error("检索老师失败！", e);
            throw new BaseException("检索老师失败！", e);
        }
    }

    @Transactional
    public void saveTutor(TutorBean bean, Integer userId) throws BaseException {
        try {
            String msg = bean.validate();
            if (msg != null && !msg.isEmpty()) {
                throw new BaseException(msg);
            }
            TutorEntity entity = null;
            if (bean.getId() != null) {
                entity = dao.get(bean.getId());
            } else {
                long count = dao.countTutorByIdNo(bean.getIdNo());
                if (count > 0) {
                    throw new BaseException("指定的老师已经添加，请检查身份证号码是否正确！");
                }
                entity = new TutorEntity();
            }
            mergeEntity(bean, userId, entity);

            dao.saveOrUpdate(entity);

            SYS_LOG.info("保存老师信息成功。 tutor=" + bean.toString());
        } catch (BaseException e) {
            SYS_LOG.error(e.getMessage(), e);
            throw e;
        } catch (Exception e) {
            SYS_LOG.error("保存老师信息失败！", e);
            throw new BaseException("保存老师信息失败！", e);
        }
    }

    public void saveTutorForImport(TutorBean bean, Integer userId) throws BaseException {
        try {
            String msg = bean.validate();
            if (msg != null && !msg.isEmpty()) {
                throw new BaseException(msg);
            }
            TutorEntity entity = dao.findTutorByIdNo(bean.getIdNo());
            if (entity == null) {
                entity = new TutorEntity();
            }

            mergeEntity(bean, userId, entity);

            dao.saveOrUpdate(entity);

            SYS_LOG.info("Excel保存老师信息成功。 tutor=" + bean.toString());
        } catch (BaseException e) {
            SYS_LOG.error(e.getMessage(), e);
            throw e;
        } catch (Exception e) {
            SYS_LOG.error("Excel保存老师信息失败！", e);
            throw new BaseException("保存老师信息失败！", e);
        }
    }

    public TutorBean updateInitTutor(Integer id) throws BaseException {
        try {
            TutorEntity entity = dao.get(id);
            if (entity == null) {
                throw new BaseException("指定的老师已经被删除！");
            }
            TutorBean bean = new TutorBean(entity);

            SYS_LOG.info("获取老师信息成功。 bean=" + bean);

            return bean;
        } catch (BaseException e) {
            SYS_LOG.error(e.getMessage(), e);
            throw e;
        } catch (Exception e) {
            SYS_LOG.error("获取老师信息失败！", e);
            throw new BaseException("获取老师信息失败！", e);
        }
    }

    @Transactional
    public void deleteTutor(List<Integer> idList) throws BaseException {
        try {
            for (Integer id : idList) {
                dao.delete(id);
            }
            SYS_LOG.info("删除老师信息成功。 idList=" + idList.toString());
        } catch (Exception e) {
            SYS_LOG.error("删除老师信息失败！", e);
            throw new BaseException("删除老师信息失败！", e);
        }
    }

    @Transactional
    public void uploadPhoto(String idNo, File photo, Integer userId) throws BaseException {
        TutorEntity tutor = dao.findTutorByIdNo(idNo);
        InputStream in = null;
        try {
            in = new FileInputStream(photo);
            byte[] b = new byte[in.available()];
            in.read(b);
            tutor.setPhoto(b);

            Timestamp ts = new Timestamp(new Date().getTime());
            tutor.setUpdatedTime(ts);
            tutor.setUpdatedUser(userId);
            dao.saveOrUpdate(tutor);
        } catch (Exception e) {
            SYS_LOG.error("上传文件处理过程中发生错误！", e);
            throw new BaseException("上传文件处理过程中发生错误！", e);
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                SYS_LOG.error("上传文件处理过程中发生错误！", e);
                throw new BaseException("上传文件处理过程中发生错误！");
            }
        }
    }

    private void mergeEntity(TutorBean bean, Integer userId, TutorEntity e) throws Exception {
        e.setAddress(bean.getAddress());
        if (bean.getBirthday() != null && !"".equals(bean.getBirthday().trim())) {
            Date birthday = BaseUtil.parseDate(bean.getBirthday());
            e.setBirthday(birthday);
        }
        e.setCategoryId(bean.getCategoryId());
        e.setCellPhone(bean.getCellPhone());
        e.setCellPhoneBak(bean.getCellPhoneBak());
        e.setIdNo(bean.getIdNo());
        e.setImAddress(bean.getImAddress());
        e.setIsMale(bean.getSex() == 1);
        e.setIntroduction(bean.getIntroduction());
        e.setIsSigned(bean.getIsSigned());
        e.setMailAddress(bean.getMailAddress());
        e.setMailAddressBak(bean.getMailAddressBak());
        e.setMajor(bean.getMajor());
        e.setName(bean.getName());
        e.setOutLine(bean.getOutLine());
        e.setPhone(bean.getPhone());
        e.setPhoneBak(bean.getPhoneBak());
        e.setPhoto(bean.getPhoto());
        e.setPrice(bean.getPrice());
        e.setStyle(bean.getStyle());
        e.setTask(bean.getTask());
        e.setType(bean.getType());
        if (bean.getRegDate() != null && !"".equals(bean.getRegDate().trim())) {
            Date dt = BaseUtil.parseDate(bean.getRegDate());
            e.setRegDate(dt);
        }
        e.setRemark(bean.getRemark());

        Timestamp ts = new Timestamp(new Date().getTime());
        if (bean.getId() == null) {
            e.setCreatedTime(ts);
            e.setCreatedUser(userId);
        } else {
            e.setUpdatedTime(ts);
            e.setUpdatedUser(userId);
        }
    }

    @Transactional
    public void importTutorXLS(String templatePath, File xlsFile, String remark) throws BaseException {
        InputStream inputXMLStream = null;
        InputStream inputXLStream = null;
        InputStream inputXLStreamForPic = null;
        try {
            inputXMLStream = new BufferedInputStream(new FileInputStream(templatePath));
            inputXLStream = new BufferedInputStream(new FileInputStream(xlsFile));
            inputXLStreamForPic = new BufferedInputStream(new FileInputStream(xlsFile));

            ExcelUtil<TutorExcelBean> util = new ExcelUtil<TutorExcelBean>();
            TutorExcelBean bean = new TutorExcelBean();
            bean.setPhoto(ExcelUtil.readerImageFromExcel(inputXLStreamForPic));
            bean.setCategoryId(CATEGORY_ID);
            bean.setRemark(remark);

            XLSReadStatus readStatus = util.readFromExcel(inputXMLStream, inputXLStream, bean,
                    BaseConstant.EXCEL_TUTOR_BEAN);
            if (readStatus.isStatusOK()) {
                HttpSession session = ServletActionContext.getRequest().getSession();
                UserBean user = (UserBean) session.getAttribute(BaseConstant.SESSION_USER_INFO_KEY);
                saveTutorForImport(bean, user.getId());
            } else {
                SYS_LOG.error("解析Excel发生错误！");
                throw new BaseException("解析Excel发生错误！");
            }
        } catch (BaseException e) {
            throw e;
        } catch (Exception e) {
            SYS_LOG.error("解析Excel发生错误！", e);
            throw new BaseException("解析Excel发生错误！", e);
        } finally {
            try {
                inputXMLStream.close();
                inputXLStream.close();
                inputXLStreamForPic.close();
            } catch (IOException e) {
                SYS_LOG.error("解析Excel发生错误！", e);
                throw new BaseException("解析Excel发生错误！", e);
            }
        }
    }

    @Transactional
    public void importTutorDOC(String templatePath, File xlsFile, String remark) throws BaseException {
        InputStream inputPROPStream = null;
        InputStream inputDOCStream = null;
        InputStream inputDOCStreamForPic = null;
        InputStream inputDOCStreamForRegDate = null;
        try {
            inputPROPStream = new FileInputStream(templatePath);
            inputDOCStream = new BufferedInputStream(new FileInputStream(xlsFile));
            inputDOCStreamForPic = new BufferedInputStream(new FileInputStream(xlsFile));
            inputDOCStreamForRegDate = new BufferedInputStream(new FileInputStream(xlsFile));

            WordUtil<TutorExcelBean> util = new WordUtil<TutorExcelBean>();
            TutorExcelBean bean = new TutorExcelBean();
            bean.setPhoto(WordUtil.readerImageFromWord(inputDOCStreamForPic));
            bean.setCategoryId(CATEGORY_ID);
            bean.setRemark(remark);

            util.readFromWord(inputPROPStream, inputDOCStream, bean);
            bean.setRegDate(null);
            bean.setIsSigned(0);
            HttpSession session = ServletActionContext.getRequest().getSession();
            UserBean user = (UserBean) session.getAttribute(BaseConstant.SESSION_USER_INFO_KEY);
            saveTutorForImport(bean, user.getId());
        } catch (BaseException e) {
            throw e;
        } catch (Exception e) {
            SYS_LOG.error("解析Excel发生错误！", e);
            throw new BaseException("解析Excel发生错误！", e);
        } finally {
            try {
                inputPROPStream.close();
                inputDOCStream.close();
                inputDOCStreamForPic.close();
                inputDOCStreamForRegDate.close();
            } catch (IOException e) {
                SYS_LOG.error("解析Excel发生错误！", e);
                throw new BaseException("解析Excel发生错误！", e);
            }
        }
    }

    public Workbook exportTutor(String templatePath, List<TutorExcelBean> tutorList) throws BaseException {
        InputStream inputXLStream = null;
        try {
            inputXLStream = new BufferedInputStream(new FileInputStream(templatePath));
            ExcelUtil<TutorExcelBean> util = new ExcelUtil<TutorExcelBean>();
            if (tutorList.size() == 1) {
                Workbook wb = util.writeToExcel(inputXLStream, tutorList.get(0), BaseConstant.EXCEL_TUTOR_BEAN);
                if (tutorList.get(0).getPhoto() != null) {
                    HSSFPatriarch patriarch = ((HSSFWorkbook) wb).getSheetAt(0).createDrawingPatriarch();
                    HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 512, 255, (short) 3, 1, (short) 4, 5);
                    patriarch.createPicture(anchor,
                            wb.addPicture(tutorList.get(0).getPhoto(), HSSFWorkbook.PICTURE_TYPE_JPEG));
                }
                return wb;
            } else {
                return util.writeToExcel(inputXLStream, tutorList, BaseConstant.EXCEL_TUTOR_BEAN_LIST);
            }
        } catch (Exception e) {
            SYS_LOG.error("导出Excel失败！", e);
            throw new BaseException("导出Excel失败！", e);
        }
    }
}
